package com.hs.srm.base.common.utils;

import com.hs.srm.base.common.annotation.DictMapping;
import com.hs.srm.base.common.base.CloneableEntity;
import com.hs.srm.base.modules.sys.entity.SysDictEntity;
import com.hs.srm.base.modules.sys.service.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sunnykid.Sunnykid;
import sunnykid.util.ClassUtils;
import sunnykid.util.UtilException;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.*;

/**
 * <p>標題：字典表常用工具类</p>
 * <p>描述：</p>
 * <p>版權：版權所有 (c) 2019</p>
 * <p>組織：厚声集团</p>
 *
 * @author 鐘曉籟
 * @version V1.0.0
 * @date 2019年1月22日 下午4:50:08
 * @since V1.0.0
 */
@Component
public class DictDataUtil {

    /**
     * 字典类型的枚举
     */
    public enum DictType {
        SYF, // 是与否
        SYF2, // 是与否2
        SDM, // 税代码
        GSXZ, // 公司性质
        BZ, // 币种
        GYSFL, // 供应商分类
        ZHZ, // 账户组
        FKTJ, // 付款条件
        GJMYTK, // 国际贸易条款
        FKTKCG, // 付款条款采购
        GJ, // 国家
        CGZ, // 采购组
        GC, // 工厂
        CGZZ, // 采购组织
        CGSQLX, // 采购申请类型
        KMLB, // 科目类别
        BM, // 部门
        WLZ, // 物料组
        JLDW, // 计量单位
        JHDZ, // 交货地址
        KCDD, // 库存地点
        HYZT, // 货源状态
        CBZX, // 成本中心
        LCZT, // 流程状态
        CGDDLX, // 采购订单类型
        SCZT, // 删除状态
        FPLX, // 发票类型
        KKLX, // 扣款类型
        FKFS, // 付款方式
        TYKM, // 统驭科目
        WULX, // 物料类型
        FHCK, // 发货仓库
        GYSXXBGLX, // 供应商信息变更类型
        GYSBGLX, // 供应商报告类型
        LYBM, // 领用部门
        HBCNSLX,//环保承诺书类型
        BGKSXZT,//环保承诺书类型
        XGBJDZT,//宣告表节点状态
        GSXZ2,//公司性质
        YPLX,//样品类型
        XXLB,//信息记录类别
        SAPSHDZ;//SAP收货地址

        /**
         * 根据枚举类型的字符串获取枚举元素
         *
         * @param typeName
         * @return
         */
        public static final DictType getType(String typeName) {
            for (DictType dictType : DictType.values()) {
                if (dictType.name().equals(typeName)) {
                    return dictType;
                }
            }
            return null;
        }
    }

    @Autowired
    private SysDictService sysDictService;

    private static SysDictService sysDictServiceObj;

    /**
     * 存贮字典数据的缓存
     */
    public static Map<Long, SysDictEntity> dictMapAll = new LinkedHashMap<>();

    /**
     * 读取并初始化字典缓存
     */
    @PostConstruct
    public void init() {
        sysDictServiceObj = this.sysDictService;
        flush();
    }

    /**
     * 获取所有字典元素
     *
     * @return
     */
    public static List<SysDictEntity> getAllDict() {
        List<SysDictEntity> list = new ArrayList<SysDictEntity>();
        list.addAll(dictMapAll.values());
        return list;
    }

    /**
     * 根据类别id获取字典元素
     *
     * @param typeId
     * @param includeParent
     * @return
     */
    public static List<SysDictEntity> getByType(Long typeId, boolean includeParent) {
        Collection<SysDictEntity> dicts = dictMapAll.values();
        List<SysDictEntity> list = new ArrayList<SysDictEntity>();
        for (SysDictEntity dict : dicts) {
            if (dict.getTypeId() != null && dict.getTypeId().longValue() == typeId.longValue()
                    || (includeParent && dict.getId().longValue() == typeId.longValue())) {
                list.add(dict);
            }
        }
        return list;
    }

    /**
     * 根据类别枚举获取字典元素
     *
     * @param dictType
     * @param includeParent
     * @return
     */
    public static List<SysDictEntity> getByType(DictType dictType, boolean includeParent) {
        SysDictEntity dict = getType(dictType);
        if (dict == null) {
            return null;
        }
        return getByType(dict.getId(), includeParent);
    }

    /**
     * 刷新缓存
     */
    public synchronized static void flush() {
        List<SysDictEntity> list = sysDictServiceObj.query(Collections.emptyMap());
        dictMapAll.clear();
        for (SysDictEntity dict : list) {
            dictMapAll.put(dict.getId(), dict);
        }
    }

    /**
     * 根据枚举获取对应的类型实体
     *
     * @param dictType
     * @return
     */
    private static SysDictEntity getType(DictType dictType) {
        Collection<SysDictEntity> dicts = dictMapAll.values();
        for (SysDictEntity dict : dicts) {
            if (dict.getTypeOrItem().intValue() == SysDictEntity.IS_TYPE && dict.getVal().equals(dictType.name())) {
                return dict;
            }
        }
        return null;
    }

    /**
     * 根据值获得名称
     *
     * @param val
     * @param dictType
     * @return
     */
    public static String valToTxt(String val, DictType dictType) {
        List<SysDictEntity> dicts = getByType(dictType, false);
        for (SysDictEntity dict : dicts) {
            if (dict.getVal().equals(val)) {
                return dict.getTxt();
            }
        }
        return null;
    }

    /**
     * 根据名称获得值
     *
     * @param txt
     * @param dictType
     * @return
     */
    public static String txtToVal(String txt, DictType dictType) {
        List<SysDictEntity> dicts = getByType(dictType, false);
        for (SysDictEntity dict : dicts) {
            if (dict.getTxt().equals(txt)) {
                return dict.getVal();
            }
        }
        return null;
    }

    /**
     * 根据id查找
     *
     * @param id
     * @return
     */
    public static SysDictEntity getById(Long id) {
        Collection<SysDictEntity> dicts = dictMapAll.values();
        for (SysDictEntity dict : dicts) {
            if (dict.getId().equals(id)) {
                return dict;
            }
        }
        return null;
    }

    /**
     * 获取所有类别
     *
     * @return
     */
    public static List<SysDictEntity> getAllType() {
        List<SysDictEntity> list = new ArrayList<>();
        Collection<SysDictEntity> dicts = dictMapAll.values();
        for (SysDictEntity dict : dicts) {
            if (dict.getTypeOrItem().intValue() == SysDictEntity.IS_TYPE) {
                list.add(dict);
            }
        }
        return list;
    }

    /**
     * 将对象中的数据字典的编码转为文字
     *
     * @param t
     * @return
     * @throws UtilException
     */
    public static <T extends CloneableEntity<?>> T parseToDictText(T t) throws UtilException {
        if (t == null) {
            return null;
        }
        T cloneT = Sunnykid.clone(t);
        Set<Field> fieldSet = ClassUtils.getAllFields(cloneT.getClass());
        for (Field field : fieldSet) {
            DictMapping dictMapping = field.getAnnotation(DictMapping.class);
            if (dictMapping != null) {
                Object val = ClassUtils.getFieldValue(cloneT, field);
                if (val != null) {
                    String vn = valToTxt(val.toString(), dictMapping.type());
                    ClassUtils.setFieldValue(cloneT, field, vn);
                }
            }
        }
        return cloneT;
    }

    /**
     * 将对象中的数据字典的文字转为编码
     *
     * @param t
     * @return
     * @throws UtilException
     */
    public static <T extends CloneableEntity<?>> T parseToDictCode(T t) throws UtilException {
        if (t == null) {
            return null;
        }
        T cloneT = Sunnykid.clone(t);
        Set<Field> fieldSet = ClassUtils.getAllFields(cloneT.getClass());
        for (Field field : fieldSet) {
            DictMapping dictMapping = field.getAnnotation(DictMapping.class);
            if (dictMapping != null) {
                Object vn = ClassUtils.getFieldValue(cloneT, field);
                if (vn != null) {
                    String val = txtToVal(vn.toString(), dictMapping.type());
                    ClassUtils.setFieldValue(cloneT, field, val);
                }
            }
        }
        return cloneT;
    }
}
